package xml_parser;

import java.io.*;
import java.util.ArrayList;             
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;                    
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;



public class ParserXmlFile extends DefaultHandler {
	 
		//List of elements;
		ArrayList<Component> myElements;
	 
	 
		String file;
		// flags
		private int classFlag;
		
		// temporary variables
		private Component tempElement;
		private Association tempAssociation;
		private String idStereotype;	
		private String nameStereotype;
		
		private HashMap<String,String> stereotypeList;


		
		 

		
	
		public ParserXmlFile() {
			myElements = new ArrayList<Component>();
			classFlag=0;
			idStereotype="";	
			nameStereotype="";
			stereotypeList= new HashMap<String,String>();
		}
	 
		public void runParser(String in,OutputStream out) throws IOException {
			parseDocument(in);
			setElementType();
			printData();
			printFile(out);
		}
	 
		private void parseDocument(String in) {
	 
			//get a factory
			SAXParserFactory spf = SAXParserFactory.newInstance();
			try {
	 
				//get a new instance of parser
				SAXParser sp = spf.newSAXParser();
	 
				//parse the file and also register this class for call backs
				sp.parse(in,this);
	 
			}
			catch(SAXException se) {
				se.printStackTrace();
			}
			catch(ParserConfigurationException pce) {
				pce.printStackTrace();
			}
			catch (IOException ie) {
				ie.printStackTrace();
			}
	 
		}
	 
		/**
		 * Iterate through the list and print
		 * the contents
		 */
		private void printData() {
			file="ELEMENTS_BEGIN\r\n\r\n";
			Iterator its = myElements.iterator();
			while(its.hasNext()) {
				//System.out.println(its.next().toString());
				file=file+its.next().toString()+"\r\n";
			}
			file=file+"\r\nELEMENTS_END\r\n\r\n\r\n";
			Set cles = stereotypeList.keySet();
			Iterator str = cles.iterator();
			while(str.hasNext()) {
					String cle = (String) str.next(); // tu peux typer plus finement ici
				   String valeur = stereotypeList.get(cle);
				file=file+cle+" : "+valeur+"\r\n";
			}
			file=file+"\r\n END\r\n\r\n\r\n";

		}
		
		
		private void printFile(OutputStream out) throws FileNotFoundException,IOException {
			byte buff[]=file.getBytes();
			for(int i=0;i<buff.length;i++)
			out.write(buff[i]);
			out.close();
		}
	 
	 
		//Event Handlers
		public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
			if(qName.equalsIgnoreCase("UML:Class")){
				classFlag ++;
				tempElement = new Component();
				tempElement.setId(attributes.getValue("xmi.id"));
				tempElement.setName(attributes.getValue("name"));
			}
			else{
				if(classFlag==1){
					if(qName.equalsIgnoreCase("UML:Stereotype"))
						tempElement.setIdref(attributes.getValue("xmi.idref"));
				}	
				else{
					if(qName.equalsIgnoreCase("UML:Stereotype")){
						idStereotype=attributes.getValue("xmi.id");
						nameStereotype=attributes.getValue("name");
					}
				}
			}
					
		}
	 

		
	 
		public void endElement(String uri, String localName, String qName) throws SAXException {
			if(qName.equalsIgnoreCase("UML:Class")){
				classFlag--;
				myElements.add(tempElement);
			}
			else{
				if(classFlag==1){
					
				}	
				else{
					if(qName.equalsIgnoreCase("UML:Stereotype")){
						if(idStereotype!=null){
							stereotypeList.put(idStereotype, nameStereotype);
						}
					}
				}
			}
		}
	 
		private void addAssociation() {
			// TODO Auto-generated method stub
			for(Component e:myElements){
				if(e.getId().equals(tempAssociation.getOwner())){
					e.addRelationship(tempAssociation);
				}
			}
		}

		private void setElementType() {
			// TODO Auto-generated method stub
			for(Component e:myElements){
				if(e!=null && e.getId()!=null){
					if(stereotypeList.containsKey(e.getIdref()))
						e.setType(stereotypeList.get(e.getIdref()));
				}
			}
			//System.out.println("taille myElements avant : " + myElements.size());
			ArrayList<Component> tempE=new ArrayList<Component>();
			for(Component e:myElements){
				if(e!=null && e.getType()!=null){
					if(e.getType().equalsIgnoreCase("MMME")|| e.getType().equalsIgnoreCase("MMMR")){
						tempE.add(e);
						//System.out.println("element : "+e.getName());
					}	
				}
			}
			myElements=new ArrayList<Component>();
			myElements.addAll(tempE);
			//System.out.println("taille myElements apres : " + myElements.size());
		}

		public ArrayList<Component> getComponent(){
			return myElements;
		}

}
